package com.hanyizhu.demostore.controller;

import com.hanyizhu.demostore.controller.ex.*;
import com.hanyizhu.demostore.entity.User;
import com.hanyizhu.demostore.service.IUserService;
import com.hanyizhu.demostore.util.JsonResult;
import org.omg.CORBA.PUBLIC_MEMBER;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * @author lenovo
 */
//@Controller
@RestController//功能:@Controller+@ResponseBody
@RequestMapping("users")
public class UserController extends BaseController{
    @Autowired
    private IUserService userService;
    @RequestMapping("reg")
    //方法二
    public JsonResult<Void> reg(User user){
        userService.reg(user);
        return new JsonResult<Void>(OK, REGMESSAGE);

    }
    /*
    //@ResponseBody //表示此方法的响应结果以Json格式数据进行数据的响应给到前端(此方法需要每个方法进行声明所以用@RestController全局定义-方法二)
    @RequestMapping("reg")
    public JsonResult<Void> reg(User user){
//        创建响应结果对象(方法一:代码重复方法二进行优化)
        JsonResult<Void> result = new JsonResult<>();
        try {
            userService.reg(user);
            result.setState(200);
            result.setMessage("用户注册成功");
        } catch (UsernameDuplicatedException e) {
            result.setState(4000);
            result.setMessage("用户名被占用");
        } catch (InserException e) {
            result.setState(5000);
            result.setMessage("注册时产生未知的异常");
        }
        return result;
    }
    */
    //2.接受数据方式:请求处理方法的参数列表设置为非pojo类型
    // Springboot会直接将请求的参数名和方法的参数名进行比较
    //如果,名称相同则会自动注入依赖
    @RequestMapping("login")
    public JsonResult<User> login(String username, String password, HttpSession session){
        User data = userService.login(username, password);
        session.setAttribute("uid",data.getUid());
        session.setAttribute("username",data.getUsername());
        //获取session中的绑定数据
        getUidFromSession(session);
        getUsernameFromSession(session);
        return new JsonResult<User>(OK, LOGINMESSAGE,data);
    }
    @RequestMapping("change_password")
    public JsonResult<Void> changePassword(String oldPassword,String newPassword,HttpSession session){
        Integer uid = getUidFromSession(session);
        String username = getUsernameFromSession(session);
        userService.changePassword(uid,username,oldPassword,newPassword);
        return new JsonResult<Void>(OK,CHANGEPASSWORDSUCCESS);
    }

    @RequestMapping("get_by_uid")
    public JsonResult<User> getByUid(HttpSession session){
        User data = userService.getByUid(getUidFromSession(session));
        return new JsonResult<>(OK,data);
    }

    @RequestMapping("change_info")
    public JsonResult<Void> changeInfo(User user,HttpSession session){
        Integer uid = getUidFromSession(session);
        String username = getUsernameFromSession(session);
        userService.changeInfo(user,uid,username);
        return new JsonResult<>(OK,CHANGEINFOSUCCESS);
    }

    /**
     * MultipartFile接口:是Springmv提供一个接口,这个接口为我们包装了
     * 获取文件类型的数据(任何类型的file都可以接收),Springboot整合了springmvc
     * 只需要再处理请求的方法参数列表上声明一个参数类型MultipartFile的参数,然后springboot
     * 自动将传递给服务的文件数据赋值给这个参数
     *
     * @RequestParam:表示请求中的参数,将请求中的参数注入请求处理方法的某个参数,
     *               如果名称不一致则可以使用@RequestParam注解进行标记
     * @param session
     * @param multipartFile
     * @return
     */
    /**设置上传文件的最大值*/
    public static final int AVATAR_MAX_SIZE = 10 * 1024 * 1024;
    /**限制上传文件的类型*/
    public static final List<String> AVATAR_TYPE = new ArrayList<>();
    //使用静态代码块来初始化常量
    static {
        AVATAR_TYPE.add("image/jpeg");
        AVATAR_TYPE.add("image/png");
        AVATAR_TYPE.add("image/bmp");
        AVATAR_TYPE.add("image/gif");
    }
    @RequestMapping("change_avatar")
    public JsonResult<String> changeAvatar(HttpSession session,
                                           @RequestParam("file") MultipartFile multipartFile){

        //判断文件是否为空
        if (multipartFile.isEmpty()){
            throw new FileEmptyException("文件为空");
        }
        //判断是否超出大小
        if (multipartFile.getSize()>AVATAR_MAX_SIZE){
            throw new FileSizeException("文件超出限制");
        }
        //判断文件的类型是否是我们规定的和后缀类型
        String contentType = multipartFile.getContentType();
        //如果集合包含某个元素返回ture contains(集合方法)
        if (!AVATAR_TYPE.contains(contentType)){
            throw new FileTypeException("文件类型不支持");
        }
        //上传的文件../upload/文件.png
        String parent = session.getServletContext().getRealPath("upload");
        //File对象指向这个路劲,file是否存在
        File dir = new File(parent);
        //检测目录是否存在
        if (!dir.exists()){
            //创建mul
            dir.mkdir();
        }
        //获取到这个文件名称,UUID工具类将生成一个新的字符串作为文件名
        String originalFilename = multipartFile.getOriginalFilename();
        //lastIndexof():返回字符串出现的最后一个位置
        int index = originalFilename.lastIndexOf(".");
        //subsstring():字符串截取 两个参数 (开始位置,结束位置),一个参数(开始位置)
        String suffix = originalFilename.substring(index);
        String filename = UUID.randomUUID().toString().toUpperCase() + suffix;
        File dest = new File(dir, filename);
        //参数file中的数据写入到这个空文件中
        try {
            //将file文件中的数据写入到dset中
            multipartFile.transferTo(dest);
        } catch (FileStateException e){
            throw new FileStateException("文件状态异常");
        } catch (IOException e) {
            throw new FileUploadIOException("文件读写异常");
        }
        Integer uid = getUidFromSession(session);
        String username = getUsernameFromSession(session);
        //返回头像的路径
        String avatar = "/upload/" + filename;
        userService.changeAvatar(uid,avatar,username);
        //返回用户头像的路劲给前端页面,将来用头像展示使用
        return new JsonResult<>(OK,CHANGEAVATAR,avatar);
    }

}
